package com.infore.siteManagement.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.infore.siteManagement.OutSide.Service.IStatisAndAlarmService;
import com.infore.siteManagement.PlatformInvocationServices.remoteService.IDataReceivingService;
import com.infore.siteManagement.repository.IStationRepository;

/**
 * 
 * Copyright: Copyright (c) 2020
 * 
 * @ClassName: StationRateUtil.java
 * @Description: 计算站点当天上传率排名
 *
 * @version: v1.0.0
 * @author: Administrator
 * @date: 2020年1月19日 下午12:41:40
 */
@Component
public class StationRateUtil {

	@Autowired
	private ObjectMapperUtil ObjectMapperUtil;
	@Autowired
	private IDataReceivingService iDataReceivingService;
	@Autowired
	private IStatisAndAlarmService iStatisAndAlarmService;
	@Autowired
	private IStationRepository iStationRepository;

	/** 多站点多因子站点mn时间段--分组得到数据 **/
	public List<Map<String, Object>> datasCenterMore(String type, String startTime, String endTime,
			List<String> mnList) {
		List<Map<String, Object>> dataResult = new ArrayList<Map<String, Object>>();// 小时天月数据结果集
		String stationMn = StringUtils.join(mnList, ",");
		// 查询单站点下因子code集合
		ResultEntity projectCodesEntity = iStatisAndAlarmService.queryProjectByStationMn(stationMn);
		List<String> projectCodes = ObjectMapperUtil.convertList(projectCodesEntity, String.class);// 站点下因子集合
		if (projectCodes == null || projectCodes.size() == 0) {
			return dataResult;
		}
		List<Map<String, Object>> dataResults = new ArrayList<Map<String, Object>>();
		if (projectCodes == null || mnList == null || projectCodes.size() == 0 || mnList.size() == 0) {
			return dataResults;
		}
		String codeString = StringUtils.join(projectCodes, ",");
		// 判断查询那钟类型的表----------如果小时分钟秒有对应的表在进行判断
//		if ("M".equals(type)) {// 分钟
//		} else if ("S".equals(type)) {// 秒
//		} else {// 查询小时表
//			ResultEntity resultEntity = iDataReceivingService.audioMoreReport(stationMn, codeString, startTime,
//					endTime);
//			if (resultEntity.getCode() != 0) {
//				return dataResults;
//			}
//			dataResults = ObjectMapperUtil.convertListMap(resultEntity);
//		}

		// 暂时按小时表来查
		// 查询小时表
		ResultEntity resultEntity = iDataReceivingService.audioMoreReport(stationMn, codeString, startTime, endTime);
		if (resultEntity.getCode() != 0) {
			return dataResults;
		}
		dataResults = ObjectMapperUtil.convertListMap(resultEntity);
		return dataResults;
	}

	/**
	 * 计算单个站点的数据上传率
	 * 
	 * @param mn
	 * @param dataResult
	 * @param startTime
	 * @param endTime
	 * @param frequnceRate
	 * @return
	 */
	public Map<String, Object> calculateRate(String mn, List<Map<String, Object>> dataResult, String startTime,
			String endTime, String frequnceRate, Integer staAndProNums) {
		if (dataResult == null || dataResult.size() == 0) {
			return null;
		}
		// 计算时间段内的时间长度
		Long rangevalue = 1L;
		Long start = DateUtil.stringToDate(startTime, DateUtil.DATE_FULL_STR).getTime();
		Long end = DateUtil.stringToDate(endTime, DateUtil.DATE_FULL_STR).getTime();
		Date date = new Date();
		if (end > date.getTime()) {
			end = date.getTime();
		}
		rangevalue = (end - start);
		// 判断数据发送频率
		Map<String, Object> result = new HashMap<String, Object>();
		Double frequnce = 1000D * 60 * 60;// 默认一小时一条
		if (StringUtils.isNotBlank(frequnceRate)) {
			String frequnceType = frequnceRate.substring(frequnceRate.length() - 1);// 例如4H,截取最后一位单位
			Double stationRate = Double.parseDouble(frequnceRate.substring(0, frequnceRate.length() - 1));// 截取单位下发送频率
			if ("M".equals(frequnceType)) {// 分钟
				frequnce = 1000 * 60 * stationRate;
			} else if ("S".equals(frequnceType)) {// 秒
				frequnce = 1000 * stationRate;
			} else if ("H".equals(frequnceType)) {
				frequnce = 1000 * 60 * 60 * stationRate;// 小时
			}
		}
		Double rateSize = rangevalue / frequnce;// 计算该时段长度内单因子应该有多少条数据
		// 计算站点下数据发送总数
		IntSummaryStatistics total = dataResult.stream()
				.collect(Collectors.summarizingInt(l -> Integer.parseInt(l.get("COUNT").toString())));
		Integer size = dataResult.size();// 因子数目
		if (staAndProNums != null) {
			size = staAndProNums;
		}
		Double rate = (total.getSum() * 1.0 / (rateSize * size)) * 100.0;
		if (rate > 100.0) {
			rate = 100.0;
		}
		result.put(mn, rate);
		return result;
	}

	/**
	 * 计算单个站点的数据有效率
	 * 
	 * @param mn
	 * @param dataResult
	 * @param startTime
	 * @param endTime
	 * @param frequnceRate
	 * @return
	 */
	public Map<String, Object> calculateRateEnable(String mn, List<Map<String, Object>> dataResult, String startTime,
			String endTime, String frequnceRate) {
		if (dataResult == null || dataResult.size() == 0) {
			return null;
		}
		// 计算站点下数据有效总数
		Map<String, Object> result = new HashMap<String, Object>();
		IntSummaryStatistics enableDate = dataResult.stream()
				.collect(Collectors.summarizingInt(l -> Integer.parseInt(l.get("FLAGS_N").toString())));
		// 计算站点下数据发送总数
		IntSummaryStatistics total = dataResult.stream()
				.collect(Collectors.summarizingInt(l -> Integer.parseInt(l.get("COUNT").toString())));
		Double rate = (enableDate.getSum() / total.getSum()) * 100.0;
		if (rate > 100.0) {
			rate = 100.0;
		}
		result.put(mn, rate);
		return result;
	}

	/**
	 * 
	 * @Function: StationRateUtil.java
	 * @Description: 计算当日有效率和当日上传率
	 *
	 * @version: v1.0.0
	 * @author: Administrator
	 * @date: 2020年1月19日 下午2:01:17 2020年1月19日 Administrator
	 */
	public Map<String, Object> uploadRateReports(String mnsList, String startTime, String endTime) {
		Map<String, Object> twoRate = new HashMap<String, Object>();
		List<String> mns = ArrayUtils.stringToList(mnsList);
		List<Map<String, Object>> stationList = iStationRepository.queryStationInfoByMns(mns);// 根据区域流域查询站点
		if (stationList != null) {
			// Map<String, Object> stationInfo = new HashMap<String, Object>();// 保存站点编号和名称
			Map<String, Object> stationProjectNum = new HashMap<String, Object>();// 保存站点编号和名称
			stationList.forEach(p -> {
				// stationInfo.put(p.get("MN").toString(), p.get("STATIONNAME"));
				stationProjectNum.put(p.get("MN").toString(), p.get("NUMS"));
			});
			// 按站点发送频率对站点分组
			Map<String, List<Map<String, Object>>> stationGroup = stationList.stream()
					.filter(f -> f.get("FREQUENCY") != null).collect(Collectors.groupingBy(
							l -> l.get("FREQUENCY").toString().substring(l.get("FREQUENCY").toString().length() - 1)));
			// 按照发送频率分组后的站点，得到数据并进行计算
			stationGroup.forEach((k, klist) -> {
				List<String> nmList = klist.stream().map(n -> n.get("MN").toString()).collect(Collectors.toList());
				List<Map<String, Object>> dataResult = new ArrayList<Map<String, Object>>();
				String type = k;
				dataResult = datasCenterMore(type, startTime, endTime, nmList);
				// 再根据mn号对站点进行分组
				Map<String, List<Map<String, Object>>> grouplist = dataResult.stream()
						.collect(Collectors.groupingBy(l -> l.get("MN").toString()));
				klist.forEach(t -> {
					// 封装数据
					String mn = t.get("MN").toString();
					Map<String, Object> singleRate = new HashMap<>();
					String frequence = t.get("FREQUENCY").toString();// 站点发送频率
					Integer staAndProNums = stationProjectNum.get(mn) == null ? null
							: NumberUtils.createInteger(stationProjectNum.get(mn).toString());
					Map<String, Object> result = calculateRate(mn, grouplist.get(mn), startTime, endTime, frequence,
							staAndProNums);// 计算单站发送频率
					Map<String, Object> enable = calculateRateEnable(mn, grouplist.get(mn), startTime, endTime,
							frequence);
					// 判断计算结果不能为空
					if (result != null && result.size() != 0) {
						if (result.keySet().contains(mn)) {
							Double rate = (Double) result.get(mn);
							singleRate.put("up_rate", String.format("%.2f", rate) + "%");
						} else {
							singleRate.put("up_rate", "0.0%");
						}
					} else {
						singleRate.put("up_rate", "0.0%");
					}
					if (enable != null && enable.size() != 0) {
						if (enable.keySet().contains(mn)) {
							Double rate = (Double) enable.get(mn);
							singleRate.put("enable_rate", String.format("%.2f", rate) + "%");
						} else {
							singleRate.put("enable_rate", "0.0%");
						}
					} else {
						singleRate.put("enable_rate", "0.0%");
					}
					twoRate.put(mn, singleRate);
				});
			});
		}
		return twoRate;
	}

}
